package mf.com.Service.impl.sys;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import mf.com.SHA256Utils;
import mf.com.Service.sys.SysUserService;
import mf.com.dto.system.AssginRoleDto;
import mf.com.dto.system.LoginDto;
import mf.com.dto.system.SysUserDto;
import mf.com.entity.system.SysRoleUser;
import mf.com.entity.system.SysUser;
import mf.com.exception.CustomExceptionHandler;
import mf.com.mapper.sys.SysRoleUserMapper;
import mf.com.mapper.sys.SysUserMapper;
import mf.com.vo.common.GlobalConstant;
import mf.com.vo.common.ResultCodeEnum;
import mf.com.vo.system.LoginVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author: lmf
 * @Create: 2024/3/23 18:28
 * Description:
 */
@Service
public class SysUserServiceImpl implements SysUserService {
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private SysRoleUserMapper roleUserMapper;

    @Override
    public SysUser findByName(String name) {
        return sysUserMapper.findByUserName(name);
    }

    @Override
    public void outLogin(String token) {
        // 删除redis中对应token
        redisTemplate.delete(GlobalConstant.TOKEN_PREFIX+token);

    }

    /**
     * 为用户分配权限
     */
    @Override
    public void  doAssign(AssginRoleDto assginRoleDto){
        final Long userId = assginRoleDto.getUserId();
        // 根据userId删除用户之前分配的角色数据
        roleUserMapper.deleteByUserId(userId);
        // 重新分配新的角色数据
        final List<Long> roleIdList = assginRoleDto.getRoleIdList();
        final ArrayList<SysRoleUser> arrayList = new ArrayList<>();
        for (Long roleId : roleIdList) {
            final SysRoleUser sysRoleUser = new SysRoleUser();
            sysRoleUser.setUserId(userId);
            sysRoleUser.setRoleId(roleId);
            arrayList.add(sysRoleUser);
        }

        for (SysRoleUser user : arrayList) {
            System.out.println(user);
        }
        roleUserMapper.doAssign(arrayList);
    }


    /**
     * 分页查询用户
     */
    @Override
    public PageInfo<SysUser> findByPage(SysUserDto sysUserDto, Integer current, Integer limit) {
        PageHelper.startPage(current, limit);
        final PageInfo<SysUser> sysUserPageInfo = new PageInfo<>(sysUserMapper.findByPage(sysUserDto));
        System.out.println("123");
        return sysUserPageInfo;
    }

    /**
     * 新增用户
     */
    @Override
    public Integer saveUser(SysUser sysUser) {
        // 查询名称是否被注册
        final SysUser sysUser1 = findByName(sysUser.getUserName());
        if(sysUser1 != null){
            throw new CustomExceptionHandler("用户名已被注册");
        }
        // 对密码进行加密
        sysUser.setPassword(SHA256Utils.sha256(sysUser.getPassword()));
        return sysUserMapper.save(sysUser);
    }

    /**
     * 更新用户
     */
    @Override
    public Integer updateUser(SysUser sysUser) {
        return sysUserMapper.update(sysUser);
    }

    /**
     * 删除用户
     */
    @Override
    public Integer deleteUser(int id) {
        return sysUserMapper.delete(id);
    }

    /**
     * 获取用户信息
     * @param token token
     * @return SysUser
     */
    @Override
    public SysUser getUserInfo(String token) {
        // 从redis中将对应用户信息数据获取
        final String s = redisTemplate.opsForValue().get(GlobalConstant.TOKEN_PREFIX+token);
        if(StrUtil.isEmpty(s)){
            throw new CustomExceptionHandler("登录过期,请重新登录");
        }
        // 将token翻入SysUser 类中
        return JSON.parseObject(s, SysUser.class);
    }

    /**
     * 登录
     * @param loginDto 登录类
     */
    @Override
    public LoginVo userLogin(LoginDto loginDto) {
        // 获取登录传递的验证码key
        final String codeKey = loginDto.getCodeKey();
        // 从redis中获取验证码
        final String captchaValue = redisTemplate.opsForValue().get(GlobalConstant.CAPTCHA_PREFIX + codeKey);

        // 检验验证码是否正确
        if(StrUtil.isEmpty(captchaValue) || !loginDto.getCaptcha().equalsIgnoreCase(captchaValue)){
            throw new CustomExceptionHandler("验证码有误请重新输入");
        }

        // 验证码通过删除redis中对应验证码
        redisTemplate.delete(GlobalConstant.CAPTCHA_PREFIX + codeKey);

        // 验证用户是否存在
        final SysUser sysUser = sysUserMapper.selectUserInfoByUsername(loginDto.getUserName());

        // 不存在直接抛出错误
        if(null == sysUser){
            throw new CustomExceptionHandler(ResultCodeEnum.LOGIN_ERROR);
        }
        // 验证密码是否正确
        final String password = loginDto.getPassword();


        if(!SHA256Utils.sha256(loginDto.getPassword()).equals(sysUser.getPassword())){
            throw new CustomExceptionHandler(ResultCodeEnum.LOGIN_ERROR);
        }

        //7 登录成功，生成用户唯一标识token
        String token = UUID.randomUUID().toString().replaceAll("-","");

        //8 把登录成功用户信息放到redis里面
        redisTemplate.opsForValue()
                .set(GlobalConstant.TOKEN_PREFIX+token,
                        JSON.toJSONString(sysUser),
                        1,
                        TimeUnit.DAYS);

        final LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        return loginVo;
    }
}
